/**
* @description 全局公共方法
*/
import { isFunction, isObject, isArray, isDate, isNumber } from '@/utils/is.js'


/**
 * @description 深度克隆
 * @param obj 克隆对象
 * @returns _obj 经过克隆之后的对象
 */
 export const cloneDeep = function(obj) {
  // 常见的非值直接返回
  if ([null, undefined, NaN, false].includes(obj)) return obj
  // 原始类型直接返回
  if (!isFunction(obj) && !isObject(obj)) return obj
  const o = isArray(obj) ? [] : {}
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      o[key] = isObject(obj[key]) ? cloneDeep(obj[key]) : obj[key]
    }
  }
  return o
}

/**
* @description 序列化对象参数
* @param { Object } obj
* @returns { String } str
*/
export const setObjToString = function(obj) {
  if (Object.keys(obj).length <= 0) return ''
  let parameters = ''
  for (const key in obj) {
    parameters += key + '=' + encodeURIComponent(obj[key]) + '&'
  }
  parameters = parameters.replace(/&$/, '')
  return '?' + parameters
}

/***
 * @description 格式化日期
 * @param time
 * @param formatStr 符号
 * @param flag 是否返回YYYY-MM-DD HH:mm:ss true 返回，false返回没有时间的日期
 * @returns {string | null}
 */
 export const formatDate = function(val, formatStr, flag) {
  const date = new Date(val)
  if (!isDate(date)) throw new Error('参数不能转化为时间')
  const year = date.getFullYear()
  let month = date.getMonth() + 1
  let day = date.getDate()
  month = month < 10 ? `0${month}` : month
  day = day < 10 ? `0${day}` : day
  if (flag) {
    let hours = date.getHours()
    let minutes = date.getMinutes()
    let seconds = date.getSeconds()
    hours = hours < 10 ? `0${hours}` : hours
    minutes = minutes < 10 ? `0${minutes}` : minutes
    seconds = seconds < 10 ? `0${seconds}` : seconds
    return `${year}${formatStr}${month}${formatStr}${day}${formatStr} ${hours}:${minutes}:${seconds}`
  } else {
    return `${year}${formatStr}${month}${formatStr}${day}`
  }
}

/***
 * @description 格式化距离当前前后的时间
 * @param num
 * @param formatStr 符号
 * @param flag 是否返回YYYY-MM-DD HH:mm:ss
 * @returns {string | null}
 */
 export const distanceFormatDate = function(num, formatStr, flag) {
  if (!isNumber(num)) throw new Error('距离的日期只能为数字')
  const date = new Date()
  const targetdayMilliseconds = date.getTime() + 1000 * 60 * 60 * 24 * num
  const distanceDate = formatDate(targetdayMilliseconds, formatStr, flag)
  return {
    currentDate: formatDate(date, formatStr, flag),
    distanceDate
  }
}

// 限制输入数字及保留几位小数点 @input="value = clearNoNum($event,0)"
export function clearNoNum(value, digit) {
  value += ''; //转为字符
  if (digit === 0) { //只能输入正整数
    value = value.replace(/[^\d]/g, "");   //清除“数字”以外的字符
  } else {
    value = value.replace(/[^\d.]/g, "");   //清除“数字”和“.”以外的字符
    value = value.replace(/\.{2,}/g, ".");  //只保留第一个. 清除多余的
    value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
    let pattern1 = new RegExp('^(\\-)*(\\d+)\\.(\\d{' + digit + '}).*$');
    // value = value.replace(/^(\-)*(\d+)\.(\d{3}).*$/,'$1$2.$3');//只能输入两个小数
    value = value.replace(pattern1, '$1$2.$3'); //只能输入两个小数
    if (value[0] === '.') {
      value = value.replace(/\./g, "0.")
    }
  }
  if (value.indexOf(".") < 0 && value != "") { //以上已经过滤，此处控制的是如果没有小数点，首位不能为类似于 01、02的金额
    // value =  parseFloat(value); //parseFloat会转为number类型，会有精度问题
    if (value.length === 2 && value[0] === '0') {
      value = value.substr(1);
    }
  }
  return value
}

/**
 * @description: 手机号隐私保护 隐藏中间四位数字
 * @param mobile
 * @returns { String }
 */
export function secrecyMobile(mobile) {
    mobile = String(mobile)
    if (!/\d{11}/.test(mobile)) {
        return mobile
    }
    return mobile.replace(/(\d{3})(\d{4})(\d{4})/, '$1****$3')
}

/***
 * @description 价格切割--将浮点数价格切割成整数部分+小数部分
 * @param price
 * @returns {Object}
 */
export function splitPrice(price) {
    // 非数字
    if (!isNumber(price)) return { x: '0', y: '.0' }

    const splitArr = price.toString().split('.')
    // 是浮点数
    if (splitArr.length === 2) {
        return { x: splitArr[0], y: '.' + splitArr[1] }
    }

    return { x: splitArr[0], y: '.0' }
}

// 阿拉伯数字转中文数字
export function NoToChinese(num) {
  if (!/^\d*(\.\d*)?$/.test(num)) {
      console.log('不是数字');
      return ""
  }
  var AA = new Array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九");
  var BB = new Array("", "十", "百", "千", "万", "亿", "点", "");
  var a = ("" + num).replace(/(^0*)/g, "").split("."),
      k = 0,
      re = "";
  for (var i = a[0].length - 1; i >= 0; i--) {
      switch (k) {
          case 0:
              re = BB[7] + re;
              break;
          case 4:
              if (!new RegExp("0{4}\\d{" + (a[0].length - i - 1) + "}$").test(a[0]))
                  re = BB[4] + re;
              break;
          case 8:
              re = BB[5] + re;
              BB[7] = BB[5];
              k = 0;
              break;
      }
      if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0) re = AA[0] + re;
      if (a[0].charAt(i) != 0) re = AA[a[0].charAt(i)] + BB[k % 4] + re;
      k++;
  }
  if (a.length > 1) //加上小数部分(如果有小数部分) 
  {
      re += BB[6];
      for (var i = 0; i < a[1].length; i++) re += AA[a[1].charAt(i)];
  }
  return re;
};

// 计算字体宽度
export function countTextLength(obj) {
	const {
		text, // 文本
		size // 字体大小
	} = obj;
	let textLength = 0
	if (text) {
		let l = 0;
		for (let j = 0; j < text.length; j++) {
			let t = text.substr(j, 1);
			const countL = countStrLength(t);
			l += countL;
		}
		// console.log('文字宽度总系数:' + l);
		textLength = l * size;
		console.log('文字总宽度:',textLength);
	}
	return textLength;
}

//计算字符长度系数
function countStrLength(t) {
	let l;
	if (/a/.test(t)) {
		l = 0.552734375
	} else if (/b/.test(t)) {
		l = 0.638671875
	} else if (/c/.test(t)) {
		l = 0.50146484375
	} else if (/d/.test(t)) {
		l = 0.6396484375
	} else if (/e/.test(t)) {
		l = 0.5673828125
	} else if (/f/.test(t)) {
		l = 0.3466796875
	} else if (/g/.test(t)) {
		l = 0.6396484375
	} else if (/h/.test(t)) {
		l = 0.61572265625
	} else if (/i/.test(t)) {
		l = 0.26611328125
	} else if (/j/.test(t)) {
		l = 0.26708984375
	} else if (/k/.test(t)) {
		l = 0.54443359375
	} else if (/l/.test(t)) {
		l = 0.26611328125
	} else if (/m/.test(t)) {
		l = 0.93701171875
	} else if (/n/.test(t)) {
		l = 0.6162109375
	} else if (/o/.test(t)) {
		l = 0.6357421875
	} else if (/p/.test(t)) {
		l = 0.638671875
	} else if (/q/.test(t)) {
		l = 0.6396484375
	} else if (/r/.test(t)) {
		l = 0.3818359375
	} else if (/s/.test(t)) {
		l = 0.462890625
	} else if (/t/.test(t)) {
		l = 0.37255859375
	} else if (/u/.test(t)) {
		l = 0.6162109375
	} else if (/v/.test(t)) {
		l = 0.52490234375
	} else if (/w/.test(t)) {
		l = 0.78955078125
	} else if (/x/.test(t)) {
		l = 0.5068359375
	} else if (/y/.test(t)) {
		l = 0.529296875
	} else if (/z/.test(t)) {
		l = 0.49169921875
	} else if (/A/.test(t)) {
		l = 0.70361328125
	} else if (/B/.test(t)) {
		l = 0.62744140625
	} else if (/C/.test(t)) {
		l = 0.6689453125
	} else if (/D/.test(t)) {
		l = 0.76171875
	} else if (/E/.test(t)) {
		l = 0.5498046875
	} else if (/F/.test(t)) {
		l = 0.53125
	} else if (/G/.test(t)) {
		l = 0.74365234375
	} else if (/H/.test(t)) {
		l = 0.7734375
	} else if (/I/.test(t)) {
		l = 0.2939453125
	} else if (/J/.test(t)) {
		l = 0.39599609375
	} else if (/K/.test(t)) {
		l = 0.634765625
	} else if (/L/.test(t)) {
		l = 0.51318359375
	} else if (/M/.test(t)) {
		l = 0.97705078125
	} else if (/N/.test(t)) {
		l = 0.81298828125
	} else if (/O/.test(t)) {
		l = 0.81494140625
	} else if (/P/.test(t)) {
		l = 0.61181640625
	} else if (/Q/.test(t)) {
		l = 0.81494140625
	} else if (/R/.test(t)) {
		l = 0.65283203125
	} else if (/S/.test(t)) {
		l = 0.5771484375
	} else if (/T/.test(t)) {
		l = 0.5732421875
	} else if (/U/.test(t)) {
		l = 0.74658203125
	} else if (/V/.test(t)) {
		l = 0.67626953125
	} else if (/W/.test(t)) {
		l = 1.017578125
	} else if (/X/.test(t)) {
		l = 0.64501953125
	} else if (/Y/.test(t)) {
		l = 0.603515625
	} else if (/Z/.test(t)) {
		l = 0.6201171875
	} else if (/[0-9]/.test(t)) {
		l = 0.58642578125
	} else if (/[\u4e00-\u9fa5]/.test(t)) {
		l = 1
	} else if (/ /.test(t)) {
		l = 0.2958984375
	} else if (/\`/.test(t)) {
		l = 0.294921875
	} else if (/\~/.test(t)) {
		l = 0.74169921875
	} else if (/\!/.test(t)) {
		l = 0.3125
	} else if (/\@/.test(t)) {
		l = 1.03125
	} else if (/\#/.test(t)) {
		l = 0.63818359375
	} else if (/\$/.test(t)) {
		l = 0.58642578125
	} else if (/\%/.test(t)) {
		l = 0.8896484375
	} else if (/\^/.test(t)) {
		l = 0.74169921875
	} else if (/\&/.test(t)) {
		l = 0.8701171875
	} else if (/\*/.test(t)) {
		l = 0.455078125
	} else if (/\(/.test(t)) {
		l = 0.333984375
	} else if (/\)/.test(t)) {
		l = 0.333984375
	} else if (/\_/.test(t)) {
		l = 0.4482421875
	} else if (/\-/.test(t)) {
		l = 0.4326171875
	} else if (/\+/.test(t)) {
		l = 0.74169921875
	} else if (/\=/.test(t)) {
		l = 0.74169921875
	} else if (/\|/.test(t)) {
		l = 0.26904296875
	} else if (/\\/.test(t)) {
		l = 0.416015625
	} else if (/\[/.test(t)) {
		l = 0.333984375
	} else if (/\]/.test(t)) {
		l = 0.333984375
	} else if (/\;/.test(t)) {
		l = 0.24072265625
	} else if (/\'/.test(t)) {
		l = 0.25634765625
	} else if (/\,/.test(t)) {
		l = 0.24072265625
	} else if (/\./.test(t)) {
		l = 0.24072265625
	} else if (/\//.test(t)) {
		l = 0.42724609375
	} else if (/\{/.test(t)) {
		l = 0.333984375
	} else if (/\}/.test(t)) {
		l = 0.333984375
	} else if (/\:/.test(t)) {
		l = 0.24072265625
	} else if (/\"/.test(t)) {
		l = 0.435546875
	} else if (/\</.test(t)) {
		l = 0.74169921875
	} else if (/\>/.test(t)) {
		l = 0.74169921875
	} else if (/\?/.test(t)) {
		l = 0.48291015625
	} else {
		l = 1
	}
	return l;
}